﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections;
using MidwayBattle.Engine;
using MidwayBattle.Models;
using MidwayBattle.Drawing;
using System.Windows.Media.Imaging;

namespace MidwayBattle.Engine
{
    class Board
    {
        public Square[,] Squares = new Square[CustomDefines.NBSQUARESX, CustomDefines.NBSQUARESY];

        CustomDefines cd = new CustomDefines();

        //--------------------------------------------------------------------------------------------------------------------------------------------

        public Board()
        {
            
            for(int x = 0; x < CustomDefines.NBSQUARESX; x++)
                for (int y = 0; y < CustomDefines.NBSQUARESY; y++)
                {
                    Squares[x, y].ContentType = CustomDefines.SQUARE_WATER;
                    Squares[x, y].AlreadyFired = false;
                    Squares[x, y].MinePresent = false;
                    Squares[x, y].IsShipPlaceable = true;
                }

        }


        //--------------------------------------------------------------------------------------------------------------------------------------------
        public void PlaceShipInMemory(int xStart, int yStart, int orient, int size)
        {
            int coordX = (orient == CustomDefines.ORIENT_TOLEFT ? (xStart - size + 1) : xStart);
            int coordY = (orient == CustomDefines.ORIENT_TOTOP ? (yStart - size + 1) : yStart);

            for (int i = 0; i < size; i++)
            {
                Squares[coordX, coordY].ContentType = CustomDefines.SQUARE_SHIP;
    

                switch(orient)
                {
                    case CustomDefines.ORIENT_TOBOTTOM :
                    case CustomDefines.ORIENT_TOTOP:
                        coordY++;
                        break;
                    
                    case CustomDefines.ORIENT_TOLEFT:
                    case CustomDefines.ORIENT_TORIGHT:
                        coordX++;
                        break;

                } // end switch

            } // end for
        }
        //--------------------------------------------------------------------------------------------------------------------------------------------

        public static Boolean IsShipPlaceable(Grid TheGrid, PlacedShip tempShip, int x, int y, int orient)
        {
            int length = tempShip.Length;
            Boolean placeable = true;

            int xToLook = 0, ytoLook = 0;

            for (int i = 0; i < length && placeable == true; i++)
            {
                foreach (System.Windows.FrameworkElement fe in TheGrid.Children)
                {
                    TagComponentProperties tcp = (TagComponentProperties)fe.Tag;

                    switch(orient)
                    {
                        case CustomDefines.ORIENT_TOBOTTOM: 
                          xToLook =  x  ;
                          ytoLook =  y+i;
                          break;

                        case CustomDefines.ORIENT_TOLEFT:
                          xToLook =  x-i  ;
                          ytoLook =  y    ;
                          break;

                        case CustomDefines.ORIENT_TORIGHT:
                          xToLook =  x+i  ;
                          ytoLook =  y    ;
                          break;

                        case CustomDefines.ORIENT_TOTOP:
                          xToLook =  x  ;
                          ytoLook =  y-i;
                          break;
                    } // END SWITCH ORIENT


                    if ((tcp != null) && ((tcp.compType == TagComponentProperties.CompTypes.TYPE_SHIP || tcp.compType == TagComponentProperties.CompTypes.TYPE_UNPLACEABLEWATER)) && (tcp.squareProp.X == xToLook) && (tcp.squareProp.Y == ytoLook))
                    {
                        placeable = false;
                        break;
                    }
                    if (!Board.IsInBoard(xToLook, ytoLook))
                    {
                        placeable = false;
                        break;
                    }                    
                
                } // END FOREACH SUR FRAMEWORK ELEMENT                
            } // END FOR GENERAL            

            return placeable;
        }

        //--------------------------------------------------------------------------------------------------------------------------------------------

        public static Boolean IsInBoard(int x, int y)
        {
            if (x < CustomDefines.NBSQUARESX && y < CustomDefines.NBSQUARESY && x >= 0 && y >= 0)
                return true;
            else
                return false;
        }

        //--------------------------------------------------------------------------------------------------------------------------------------------

        public Boolean IsEmpty(Grid TheGrid, int x, int y)
        {
            foreach (System.Windows.FrameworkElement fe in TheGrid.Children)
            {
                TagComponentProperties tcp = (TagComponentProperties)fe.Tag;

                if ((tcp != null) && (tcp.compType == TagComponentProperties.CompTypes.TYPE_SQUARE) && (tcp.squareProp.X == x) && (tcp.squareProp.Y == y))
                {
                    return true;
                }
            }

            return false;
        }

        //--------------------------------------------------------------------------------------------------------------------------------------------

        public AvailablePlacement GetFirstPossiblePlacement(Grid TheGrid, PlacedShip tempShip, int x, int y)
        {
            AvailablePlacement avail = new AvailablePlacement();
            Boolean found = false;

            int i;

            for (i = 0; (i < 4 && found == false); i++)
            {
                int orient = (int)cd.ORIENT_TAB[i];
                if (IsShipPlaceable(TheGrid, tempShip, x, y, orient)) 
                    found = true;

            }

            avail.found = found;
            if(found) avail.Orient = (int)cd.ORIENT_TAB[i];
            return avail;

        }

        //--------------------------------------------------------------------------------------------------------------------------------------------

        public int GotoNextOrientation(Grid TheGrid, PlacedShip tempShip, int x, int y, int CurrentOrientation)
        {
            int NextOrientation = CurrentOrientation;
            int NbAttempts = 0;
            Boolean found = false;

            CustomDefines cd = new CustomDefines();

            do
            {
                NbAttempts++;
                
                // We increase the NextOrientation, with checking
                NextOrientation++;
                if (NextOrientation == 4) NextOrientation = CustomDefines.ORIENT_TOBOTTOM;


                // We check the different possibilites to place the ship, rounding clockwise
                int orient = (int)cd.ORIENT_TAB[NextOrientation];
                if (IsShipPlaceable(TheGrid, tempShip, x, y, orient))
                {
                    found = true;
                    NextOrientation = orient;

                }               

            } while (found == false && NbAttempts < 4);

            return NextOrientation;
        }

        //--------------------------------------------------------------------------------------------------------------------------------------------
      

    }
}
